package net.chasing.androidbaseconfig.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * description : 正则工具类 提供验证邮箱、手机号码、电话号码、身份证号码、数字等方法
 * ^[0-9]{6}$
 * ^用于匹配开头，$用于匹配结尾，匹配字符串长度等于6，避免长度大于6，但字符串中间的6个字符符合条件的情况
 */
public class RegexUtils {

    /**
     * 验证Email
     *
     * @param email email地址，格式：zhangsan@sina.com，zhangsan@xxx.com.cn，xxx代表邮件服务商
     * @return 验证成功返回true，验证失败返回false ^ ：匹配输入的开始位置。 \：将下一个字符标记为特殊字符或字面值。
     * ：匹配前一个字符零次或几次。 + ：匹配前一个字符一次或多次。 (pattern) 与模式匹配并记住匹配。 x|y：匹配 x 或
     * y。 [a-z] ：表示某个范围内的字符。与指定区间内的任何字符匹配。 \w ：与任何单词字符匹配，包括下划线。
     * <p>
     */
    public static boolean checkEmail(String email) {
        String regex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
        return Pattern.matches(regex, email);
    }

    /**
     * 验证身份证号码
     *
     * @param idCard 居民身份证号码15位或18位，最后一位可能是数字或字母
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkIdCard(String idCard) {
        //        String regex = "[1-9]\\d{13,16}[a-zA-Z0-9]{1}";
        String regex = "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)";
        return Pattern.matches(regex, idCard);
    }

    /**
     * 验证手机号码（支持国际格式，+86135xxxx...（中国内地），+00852137xxxx...（中国香港））
     *
     * @param mobile 移动、联通、电信运营商的号码段
     *               中国电信号段
     *               133、149、153、173、177、180、181、189、199
     *               1349(卫)、141(物)、162(虚)、1740(0-5)(卫)、190(5G)、191、193
     *               中国联通号段
     *               130、131、132、145、155、156、166、175、176、185、186
     *               140(物)、146(物)、167(虚)、196(5G)
     *               中国移动号段
     *               134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188、198
     *               144(物)、148(物)、165(虚)、172(物)、195、197(5G)
     *               中国广电号段
     *               192(5G)
     *               其他号段
     *               14号段以前为上网卡专属号段，如中国联通的是145，中国移动的是147等等。
     *               虚拟运营商
     *               电信：1700、1701、1702
     *               联通：1704、1707、1708、1709、171
     *               移动：1703、1705、1706
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkMobile(String mobile) {
        String regex = "^1([3589]\\d|4[01465789]|6[2567]|7[0-8])\\d{8}$";
        return Pattern.matches(regex, mobile);
    }

    /**
     * 验证固定电话号码
     *
     * @param phone 电话号码，格式：国家（地区）电话代码 + 区号（城市代码） + 电话号码，如：+8602085588447
     *              <p>
     *              <b>国家（地区） 代码 ：</b>标识电话号码的国家（地区）的标准国家（地区）代码。它包含从 0 到 9
     *              的一位或多位数字， 数字之后是空格分隔的国家（地区）代码。
     *              </p>
     *              <p>
     *              <b>区号（城市代码）：</b>这可能包含一个或多个从 0 到 9 的数字，地区或城市代码放在圆括号——
     *              对不使用地区或城市代码的国家（地区），则省略该组件。
     *              </p>
     *              <p>
     *              <b>电话号码：</b>这包含从 0 到 9 的一个或多个数字
     *              </p>
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkPhone(String phone) {
        // String regex = "(\\+\\d+)?(\\d{3,4}\\-?)?\\d{7,8}$";
        String regex = "^1\\d{10}$";
        return Pattern.matches(regex, phone);
    }

    /**
     * 验证整数（正整数和负整数）
     *
     * @param digit 一位或多位0-9之间的整数
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkDigit(String digit) {
        String regex = "-?[1-9]\\d+";
        return Pattern.matches(regex, digit);
    }

    /**
     * 验证整数和浮点数（正负整数和正负浮点数）
     *
     * @param decimals 一位或多位0-9之间的浮点数，如：1.23，233.30
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkDecimals(String decimals) {
        String regex = "-?[1-9]\\d+(\\.\\d+)?";
        return Pattern.matches(regex, decimals);
    }

    /**
     * 只能输入有1~2位小数的正实数
     *
     * @param decimals 文本
     * @return 是否满足条件
     */
    public static boolean checkTwoDecimals(String decimals) {
        String regex = "^[0-9]+(.[0-9]{1,2})?$";
        return Pattern.matches(regex, decimals);
    }

    /**
     * 验证空白字符
     *
     * @param blankSpace 空白字符，包括：空格、\t、\n、\r、\f、\x0B
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkBlankSpace(String blankSpace) {
        String regex = "\\s+";
        return Pattern.matches(regex, blankSpace);
    }

    /**
     * 验证中文
     *
     * @param chinese 中文字符
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkChinese(String chinese) {
        String regex = "^[\u4E00-\u9FA5]+$";
        return Pattern.matches(regex, chinese);
    }

    /**
     * 验证日期（年月日）
     *
     * @param birthday 日期，格式：1992-09-03，或1992.09.03
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkBirthday(String birthday) {
        String regex = "[1-9]{4}([-./])\\d{1,2}\\1\\d{1,2}";
        return Pattern.matches(regex, birthday);
    }

    /**
     * 验证URL地址
     *
     * @param url 格式：http://blog.csdn.net:80/xyang81/article/details/7705960? 或
     *            http://www.csdn.net:80
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkURL(String url) {
        String regex = "(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?";
        return Pattern.matches(regex, url);
    }

    /**
     * 匹配中国邮政编码
     *
     * @param postcode 邮政编码
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkPostcode(String postcode) {
        String regex = "[1-9]\\d{5}";
        return Pattern.matches(regex, postcode);
    }

    /**
     * 匹配IP地址(简单匹配，格式，如：192.168.1.1，127.0.0.1，没有匹配IP段的大小)
     *
     * @param ipAddress IPv4标准地址
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean checkIpAddress(String ipAddress) {
        String regex = "[1-9](\\d{1,2})?\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))";
        return Pattern.matches(regex, ipAddress);
    }

    public static boolean checkNickname(String nickname) {
        String regex = "^[a-zA-Z0-9\u4E00-\u9FA5_]+$";
        return Pattern.matches(regex, nickname);
    }

    public static boolean hasCrossSciptRiskInAddress(String str) {
        String regex = "[`~!@#$%^&*+=|{}':;,\\[\\].<>！￥…—【】‘；：”“’。，、？-]";
        if (str != null) {
            str = str.trim();
            Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
            Matcher m = p.matcher(str);
            return m.find();
        }
        return false;
    }

    /**
     * 验证密码（密码格式必须是6-16位数字字母组合）
     * (?![0-9]+$) 表示不能全是数字0-9
     * (?![a-zA-Z]+$) 表示不能全是字母
     * [0-9A-Za-z]{6,16} 表示匹配[]内的字符，长度6-16
     *
     * @param password 密码
     * @return 是否满足条件
     */
    public static boolean checkPassword(String password) {
        String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$";
        return Pattern.matches(regex, password);
    }

    public static boolean checkPasswordWithSpecialString(String password) {
        String regex = "^[A-Za-z0-9|!@#$%^&_*]{6,16}$";
        return Pattern.matches(regex, password);
    }

    /**
     * 验证支付密码（密码格式必须是6位数字）
     *
     * @param password 支付密码
     * @return 是否满足条件
     */
    public static boolean checkPayPassword(String password) {
        String regex = "^[0-9]{6}$";
        return Pattern.matches(regex, password);
    }

    /**
     * 字符串截取--拼接实现
     */
    public static String hidePhone(String phone) {
        if (phone != null && phone.length() == 11) {
            // 截取前面三位
            String start = phone.substring(0, 3);
            // 中间填充五颗星 ****
            String middle = "*****";
            // 截取末尾三位
            String end = phone.substring(8, 11);
            return start.concat(middle).concat(end);
        }
        return phone;
    }

    /**
     * 获取emoji表情字符个数
     */
    public static int emojiCount(String str) {
        int emojiCount = 0;

        for (int i = 0; i < str.length(); i++) {
            int type = Character.getType(str.charAt(i));
            if (type == Character.SURROGATE || type == Character.OTHER_SYMBOL) {
                emojiCount++;
            }
        }
        return emojiCount / 2;
    }
    /**
     * 将中文标点符号替换成英文表达符号
     */
    public static String replaceChineseSymbol(String str) {
        return str.replaceAll(" ", "")
                .replaceAll("，", ",")
                .replaceAll("。", ".")
                .replaceAll("？", "?")
                .replaceAll("！", "!")
                .replaceAll("、", ",")
                .replaceAll("：", ":")
                .replaceAll("；", ";")
                .replaceAll("（", "(")
                .replaceAll("）", ")")
                .replaceAll("【", "[")
                .replaceAll("】", "]")
                .replaceAll("『", "{")
                .replaceAll("』", "}")
                .replaceAll("《", "<<")
                .replaceAll("》", ">>")
                .replaceAll("—", "-")
                .replaceAll("——", "-")
                .replaceAll("…", "...")
                .replaceAll("……", "...")
                .replaceAll("“", "\"")
                .replaceAll("”", "\"")
                .replaceAll("‘", "'")
                .replaceAll("’", "'");
    }
}
